package rolesystem.middle.GUI;

import java.awt.*;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

import rolesystem.agentlogic.parameters.ConfigurationParameters;
import rolesystem.jade.agents.carry.carrier.ExplorerSL;
import rolesystem.middle.managers.CounterManager;
import rolesystem.middle.managers.EnvironmentManager;
import rolesystem.middle.managers.KnownEnvironmentManager;
import rolesystem.middle.parameters.DefaultParameters;
import rolesystem.middle.parameters.DefaultParametersGUI;
import rolesystem.middle.utilityclasses.AgentData;
import rolesystem.middle.utilityclasses.AgentMap;
import rolesystem.middle.utilityclasses.KnownEnvironment;
import rolesystem.middle.utilityclasses.PositionSq;
import rolesystem.middle.utilityclasses.Square;
import rolesystem.middle.utilityclasses.Utils;

public class EnvVisualizer extends Canvas
{
	private static final long serialVersionUID = 3111297938794921923L;
	private static Image offScreenImage;
	private Graphics offScreenGraphics;
	private static Image offScreenImageDrawed;
	
	private Graphics offScreenGraphicsDrawed;
	
	private static int cellSize;
	private static Dimension dim;
	
	private static Semaphore semaphore;
	private static Semaphore semaphoreUp;
	
	private static boolean DRAW_NEST;
	private static boolean DRAW_KNOWN;
	
	static
	{	
		DRAW_NEST=DefaultParameters.DRAW_NEST;
		DRAW_KNOWN=DefaultParameters.DRAW_KNOWN;
		
		EnvVisualizer.semaphore = new Semaphore(1);
		EnvVisualizer.semaphoreUp = new Semaphore(1); 
	}
	
	public EnvVisualizer( int cellSize_p, int dim_x,int dim_y) 
	{
		cellSize = cellSize_p;
		
		setBackground(DefaultParametersGUI.BACKGROUND_COLOR);
		dim = new Dimension( dim_x, dim_y);
	}
	
	public static void updateAgent(int agent_id,PositionSq updatedPosition)
	{
		semaphore.acquireUninterruptibly();
		
		AgentMap.setAgentPosition(agent_id, updatedPosition); 
		
		semaphore.release();
	}
	
	/** 
	 * Use double buffering.
	 * @see java.awt.Component#update(java.awt.Graphics)
	 */
	public void update(Graphics g) 
	{
		semaphoreUp.acquireUninterruptibly();
		
		Dimension d = getSize();
		
		if ((offScreenImage == null)) 
		{
			offScreenImage = createImage(d.width, d.height);
			offScreenGraphics = offScreenImage.getGraphics();
		}
		
		paint(offScreenGraphics);
		g.drawImage(offScreenImage, 0, 0, null);
		
		semaphoreUp.release();
	}
	
	public void paint(Graphics g) 
	{
		semaphore.acquireUninterruptibly();  
		
		// Draw grid on background image, which is faster
		if (offScreenImageDrawed == null) 
		{
			Dimension d = getSize();
			
			offScreenImageDrawed = createImage(d.width, d.height);
			offScreenGraphicsDrawed = offScreenImageDrawed.getGraphics();
			
			// draw background
			offScreenGraphicsDrawed.setColor(getBackground());
			offScreenGraphicsDrawed.fillRect(0, 0, d.width, d.height);
			offScreenGraphicsDrawed.setColor(Color.gray);
			offScreenGraphicsDrawed.fillRect(0, 0, cellSize * dim.width - 1, cellSize * dim.height - 1);
			offScreenGraphicsDrawed.setColor(getBackground());
			
			for (int x = 1; x < dim.width; x++) 
				offScreenGraphicsDrawed.drawLine(x * cellSize - 1, 0, x * cellSize - 1, cellSize * dim.height - 1);
			for (int y = 1; y < dim.height; y++) 
				offScreenGraphicsDrawed.drawLine( 0, y * cellSize - 1, cellSize * dim.width - 1, y * cellSize - 1);
		}
		g.drawImage(offScreenImageDrawed, 0, 0, null);
		
		g.setColor(DefaultParametersGUI.OBJECT_COLOR);	// Draw Objects
		
		for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
		{
			for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
			{
				if(EnvironmentManager.getObjectExist(new PositionSq(i,j)))  
					g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
			}    
		}
		
		g.setColor(DefaultParametersGUI.OBSTACLES_COLOR);   // Draw Obstacles
		
		for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
		{
			for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
			{
				if(EnvironmentManager.getObstacle(new PositionSq(i,j))==true)  
					g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
			}    
		}
		
				
		if(DRAW_NEST) // Draw Nest
		{	
			g.setColor(DefaultParametersGUI.NEST_COLOR);
			g.fillRect(1 * cellSize, 1 * cellSize, cellSize - 1, cellSize - 1);
		}
		
		if(DRAW_KNOWN) // Draw Known Squares
		{
			for(int k=0;k<CounterManager.get(ConfigurationParameters.ID_COUNTER);k++)
			{	
				g.setColor(Utils.getColorbyIndex(k));
				KnownEnvironment knowEnv=KnownEnvironmentManager.getKnownEnvironments(k);
				if(knowEnv==null)
					continue;
				
				for(int i=0;i< EnvironmentManager.ENV_MAX_X; i++)
				{
					for(int j=0;j< EnvironmentManager.ENV_MAX_Y; j++)
					{
						if(knowEnv.getKnownPosition(new PositionSq(i,j)).getKnown()==true && EnvironmentManager.getObstacle(new PositionSq(i,j))==false)  
							g.fillRect(i * cellSize, j * cellSize, cellSize - 1, cellSize - 1); 
					}    
				}
			}
			
		}	
		
		g.setColor(DefaultParametersGUI.AGENT_COLOR);  // Draw Agents
		
		for(int i=0;i<AgentMap.getSize();i++)
		{
			g.setColor(Color.black);
			g.fillRect(AgentMap.getPositionByIndex(i).x  * cellSize, AgentMap.getPositionByIndex(i).y * cellSize, cellSize - 1, cellSize - 1); 
			
			g.setFont(DefaultParametersGUI.AGENT_NUMBER_FONT);
			g.setColor(DefaultParametersGUI.AGENT_NUMBER_COLOR);
			FontMetrics fm = g.getFontMetrics();
			int w = fm.stringWidth(String.valueOf(AgentMap.getIdByIndex(i)));
			int h = fm.getAscent();
			
			float x_offset;
			if(AgentMap.getIdByIndex(i)>=10)
				x_offset=1/3;
			else
				x_offset=2/3;
			g.drawString(String.valueOf(AgentMap.getIdByIndex(i)), (AgentMap.getPositionByIndex(i).x  * cellSize)+(int)(w*x_offset), (AgentMap.getPositionByIndex(i).y  * cellSize)+ h*(4/3) );
		}  
		
		semaphore.release();	
	}
	
}



